/*
 * 配置信息类
 *
 * 以单例模式存储配置信息
 *
 **/

#pragma once

#include <unordered_map>
#include "level.hpp"
#include "util.hpp"

namespace easylog
{
#if defined (__APPLE__)
        using color_mode = std::unordered_map<int, color_enum>; // clang won't convert level and colors to int
#else
        using color_mode = std::unordered_map<level::lv_enum, color_enum>;
#endif

    class config
    {
    public:
        static config& instance()
        {
            static config inst;
            return inst;
        }

        level::lv_enum get_level()            { return _level;          }
        std::string    get_pattern()          { return _pattern;        }
        bool           get_oncolor()          { return _colorful;       }
        color_mode     get_color()            { return _colorset;       }
        std::string    get_fn_pattern()       { return _fn_patt;        }
        size_t         get_max_file_size()    { return _max_file_size;  }
        size_t         get_max_live_time()    { return _max_live_time;  }
        size_t         get_max_history()      { return _max_history;    }
        size_t         get_total_size_cap()   { return _total_size_cap; }
        bool           get_work_type()        { return _work_type;      }
        size_t         get_thread_num()       { return _thread_num;     }
        size_t         get_buffer_size()      { return _buffer_size;    }
        size_t         get_buffer_incr()      { return _buffer_incr;    }
        size_t         get_buffer_thres()     { return _buffer_thres;   }

        void set_level(level::lv_enum lv)            { _level = lv;            }
        void set_pattern(const std::string& p)       { _pattern = p;           }
        void set_colorful(bool color)                { _colorful = color;      }
        void set_color(const color_mode& cols)       { _colorset = cols;       }
        void set_fn_pattern(const std::string& patt) { _fn_patt = patt;        }
        void set_max_file_size(size_enum size)       { _max_file_size = size;  }
        void set_max_live_time(time_enum time)       { _max_live_time = time;  }
        void set_max_history(size_t num)             { _max_history = num;     }
        void set_total_size_cap(size_enum size)      { _total_size_cap = size; }
        void set_work_type(bool type)                { _work_type = type;      }
        void set_thread_num(size_t num)              { _thread_num = num;      }
        void set_buffer_size(size_t size)            { _buffer_size = size;    }
        void set_buffer_incr(size_t incr)            { _buffer_incr = incr;    }
        void set_buffer_thres(size_t thre)           { _buffer_thres = thre;   }

    private:
        config()
            : _level(default_level)
            , _pattern(default_pattern)
            , _colorful(default_colorful)
            , _colorset(default_colorset)
            , _fn_patt(default_fn_pattern)
            , _max_history(default_max_history)
            , _max_live_time(default_max_live_time)
            , _max_file_size(default_max_file_size)
            , _total_size_cap(default_total_size_cap)
            , _work_type(default_work_type)
            , _thread_num(default_thread_num)
            , _buffer_size(default_buffer_size)
            , _buffer_incr(default_buffer_incrment)
            , _buffer_thres(default_buffer_threshold)
        {}

        config(const config&) = delete;
        config& operator=(const config&) = delete;

        level::lv_enum default_level    = level::debug;
        std::string    default_pattern  = "[%d{%F %H:%M:%S}][%p][%t][%c][%f:%l]%T%m%T[%a]%n";
        bool           default_colorful = false;
        color_mode     default_colorset =
        {
            { level::debug, color_enum::none         },
            { level::info,  color_enum::green        },
            { level::warn,  color_enum::yellow       },
            { level::error, color_enum::light_purple },
            { level::fatal, color_enum::red          },
        };
        std::string  default_fn_pattern     = "log-%d{%Y%m%d-%H%M%S}.log";
        size_t       default_max_history    = 10;
        time_enum    default_max_live_time  = time_enum::t2sec;
        size_enum    default_max_file_size  = size_enum::m1MB;
        size_enum    default_total_size_cap = size_enum::m300MB;

        bool   default_work_type            = false;
        size_t default_thread_num           = 1;
        size_t default_buffer_size          = size_enum::m10KB;
        size_t default_buffer_incrment      = size_enum::m2KB;
        size_t default_buffer_threshold     = size_enum::m20KB;

    private:
        level::lv_enum _level;
        std::string _pattern;

        bool _colorful;
        color_mode _colorset;

        std::string _fn_patt;
        size_t _max_history;
        time_enum _max_live_time;
        size_enum _max_file_size;
        size_enum _total_size_cap;

        bool _work_type;
        size_t _thread_num;
        size_t _buffer_size;
        size_t _buffer_incr;
        size_t _buffer_thres;
    };
}
